package com.lpf.streamAPI;

import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.junit.Test;

import com.lpf.common.Employee;
import com.lpf.common.Status;


/**
 * 归约
 */
@SuppressWarnings("ALL")
public class StreamAPI_End_3 {
	
	List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 79, 6666.66, Status.BUSY),
			new Employee(101, "张三", 18, 9999.99, Status.FREE),
			new Employee(103, "王五", 28, 3333.33, Status.VOCATION),
			new Employee(104, "赵六", 8, 7777.77, Status.BUSY),
			new Employee(104, "赵六", 8, 7777.77, Status.FREE),
			new Employee(104, "赵六", 8, 7777.77, Status.FREE),
			new Employee(105, "田七", 38, 5555.55, Status.BUSY)
	);
	
	//collect——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法
	@Test
	public void testCollect(){
		
		System.out.println("\n---------Collectors.toList()---------------------------------------------");
		List<String> list = emps.stream()
								.map(Employee::getName)
								.collect(Collectors.toList());
		list.forEach(System.out::println);
		
		
		System.out.println("\n---------Collectors.toSet()---------------------------------------------");
		Set<String> set = emps.stream()
							  .map(Employee::getName)
							  .collect(Collectors.toSet());
		set.forEach(System.out::println);

		
		System.out.println("\n---------Collectors.toCollection(HashSet::new)---------------------------------------------");
		HashSet<String> hs = emps.stream()
								 .map(Employee::getName)
								 .collect(Collectors.toCollection(HashSet::new));
		hs.forEach(System.out::println);
		
		
		System.out.println("\n---------Collectors.maxBy()---------------------------------------------");
		Optional<Double> max = emps.stream()
								   .map(Employee::getSalary)
								   .collect(Collectors.maxBy(Double::compare));
		System.out.println(max.get());
		
		
		System.out.println("\n---------Collectors.minBy()---------------------------------------------");
		Optional<Employee> op = emps.stream()
									.collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
		System.out.println(op.get());
		
		
		System.out.println("\n---------Collectors.toList()---------------------------------------------");
		Double sum = emps.stream()
				 		 .collect(Collectors.summingDouble(Employee::getSalary));
		System.out.println(sum);
		
		
		System.out.println("\n---------Collectors.averagingDouble()---------------------------------------------");
		Double avg = emps.stream()
				  		 .collect(Collectors.averagingDouble(Employee::getSalary));
		System.out.println(avg);
		
		
		System.out.println("\n---------Collectors.counting()---------------------------------------------");
		Long count = emps.stream()
				 		 .collect(Collectors.counting());
		System.out.println(count);
		
		
		System.out.println("\n---------Collectors.summarizingDouble()---------------------------------------------");
		DoubleSummaryStatistics dss = emps.stream()
								  		  .collect(Collectors.summarizingDouble(Employee::getSalary));
		System.out.println(dss.getMax());
		
		
		System.out.println("\n---------Collectors.groupingBy()---------------------------------------------");
		// 分组
		Map<Status, List<Employee>> map = emps.stream()
											  .collect(Collectors.groupingBy(Employee::getStatus));
		System.out.println(map);
		
		
		System.out.println("\n---------Collectors.groupingBy()---------------------------------------------");
		// 多级分组
		Map<Status, Map<String, List<Employee>>> map2 = emps.stream()
							.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
								if (e.getAge() >= 60)
									return "老年";
								else if (e.getAge() >= 35)
									return "中年";
								else
									return "成年";
							})));
		System.out.println(map2);
		
		
		System.out.println("\n---------Collectors.partitioningBy()---------------------------------------------");
		// 分区
		Map<Boolean, List<Employee>> map3 = emps.stream()
											   .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
		System.out.println(map3);
		
		
		System.out.println("\n---------Collectors.joining()---------------------------------------------");
		String str = emps.stream()
						 .map(Employee::getName)
						 .collect(Collectors.joining("," , "----", "----"));
		System.out.println(str);
		
		
		System.out.println("\n---------Collectors.reducing()---------------------------------------------");
		Optional<Double> op2 = emps.stream()
								   .map(Employee::getSalary)
								   .collect(Collectors.reducing(Double::sum));
		System.out.println(op2.get());
	}
	
	
/**
---------Collectors.toList()---------------------------------------------
李四
张三
王五
赵六
赵六
赵六
田七

---------Collectors.toSet()---------------------------------------------
李四
张三
王五
赵六
田七

---------Collectors.toCollection(HashSet::new)---------------------------------------------
李四
张三
王五
赵六
田七

---------Collectors.maxBy()---------------------------------------------
9999.99

---------Collectors.minBy()---------------------------------------------
Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]

---------Collectors.toList()---------------------------------------------
48888.840000000004

---------Collectors.averagingDouble()---------------------------------------------
6984.120000000001

---------Collectors.counting()---------------------------------------------
7

---------Collectors.summarizingDouble()---------------------------------------------
9999.99

---------Collectors.groupingBy()---------------------------------------------
{VOCATION=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], BUSY=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]], FREE=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]]}

---------Collectors.groupingBy()---------------------------------------------
{VOCATION={成年=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}, BUSY={成年=[Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY]], 老年=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY]], 中年=[Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}, FREE={成年=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]]}}

---------Collectors.partitioningBy()---------------------------------------------
{false=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], true=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY], Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}

---------Collectors.joining()---------------------------------------------
----李四,张三,王五,赵六,赵六,赵六,田七----

---------Collectors.reducing()---------------------------------------------
48888.84000000001

*/
}
